package com.xiao.androidcompose01.file

import android.app.Application
import okio.Buffer
import okio.FileSystem
import okio.Path
import okio.Path.Companion.toOkioPath
import org.koin.core.annotation.Single
import kotlin.reflect.KProperty

data class AccountLogin(
   val phone: String,
   val password: String,
   val jsessionid: String?
)

@Single
class AccountFileUtil (private val application: Application){
   fun saveAccount(phone: String,password: String,jsessionid: String){
      val cacheDir by CacheDirDelegate(application)
      val accountDir = cacheDir.resolve("account")
      FileSystem.SYSTEM.openReadWrite(accountDir).use {
         it.lock.lock()
         val buffer = Buffer()
         val phoneByte = phone.toByteArray()
         val password = password.toByteArray()
         val jsessionid = jsessionid.toByteArray()
         val SPLITE = '\uE000'.toString().toByteArray()
         val byteArray = ByteArray(phoneByte.size + SPLITE.size + password.size + SPLITE.size + jsessionid.size)
         val byteList = ArrayList<Byte>()
         phoneByte.forEach {
            byteList.add(it)
         }
         SPLITE.forEach {
            byteList.add(it)
         }
         password.forEach {
            byteList.add(it)
         }
         SPLITE.forEach {
            byteList.add(it)
         }
         jsessionid.forEach {
            byteList.add(it)
         }
         byteList.forEachIndexed { index, byte ->
            byteArray[index] = byte
         }
         buffer.write(byteArray)
         buffer.flush()
         it.sink().write(buffer,buffer.size)
         it.flush()
         it.lock.unlock()
      }
   }
   
   fun loadAccount():AccountLogin?{
      val cacheDir by CacheDirDelegate(application)
      val accountDir = cacheDir.resolve("account")
      if (FileSystem.SYSTEM.exists(accountDir).not()){
         return null
      }
      val SPLITE = '\uE000'.toString()
      FileSystem.SYSTEM.openReadOnly(accountDir).use {
         it.lock.lock()
         val buffer = Buffer()
         it.source().use {
            buffer.writeAll(it)
         }
         val byteArray = buffer.readByteArray()
         val result = byteArray.toString(Charsets.UTF_8)
         val splits = result.split(SPLITE)
         val phone = splits.getOrNull(0) ?: return null
         val password = splits.getOrNull(1)?: return null
         val jsessionid = splits.getOrNull(2) ?: return null
         return AccountLogin(phone,password,jsessionid)
      }
      return null
   }
   
   fun removeAccount(){
      val cacheDir by CacheDirDelegate(application)
      val accountDir = cacheDir.resolve("account")
      FileSystem.SYSTEM.delete(accountDir)
   }
}

class CacheDirDelegate(private val value: Application){
   operator fun getValue(thisRef: Any?, property: KProperty<*>): Path {
      return value.cacheDir.toPath().toOkioPath()
   }
}